//
//  BluetoothSensor.m
//  Pennyworth
//
//  Created by Chris Karr on 12/24/07.
//  Copyright 2007 Chris J. Karr. All rights reserved.
//

#import "BluetoothSensor.h"
#import <IOBluetooth/objc/IOBluetoothDevice.h>
#import <IOBluetooth/objc/IOBluetoothSDPServiceRecord.h>
#import "Context.h"
#import "Learner.h"
#import "SensorsController.h"

#define LOG_BLUETOOTH @"Log_Bluetooth"
#define BLUETOOTH_SCAN @"Bluetooth_Scan"

#define SENSOR_NAME @"Bluetooth Devices"

@implementation BluetoothSensor

- (void) awakeFromNib
{
	started = YES;
	
	search = nil;
	searching = NO;

	timer = [[NSTimer scheduledTimerWithTimeInterval:120 target:self selector:@selector(update:) userInfo:nil repeats:YES] retain];

	[[SensorsController sharedController] addSensor:SENSOR_NAME];
	
//	location == @"Unknown";
//	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(processPrediction:) name:PREDICTION_FETCHED object:nil];
}

/*- (void) processPrediction:(NSNotification *) note
{
	NSDictionary * userInfo = [note userInfo];

	NSString * key = [userInfo valueForKey:KEY];
	
	if ([key isEqualToString:@"Location"])
		location = [userInfo valueForKey:PREDICTION];
} */

- (void) update:(NSTimer *) theTimer
{
	if (![[SensorsController sharedController] canFire:SENSOR_NAME])
	{
		NSMutableDictionary * note = [NSMutableDictionary dictionary];
		[note setValue:SENSOR_NAME forKey:OBSERVATION_SENSOR];
		[[NSNotificationCenter defaultCenter] postNotificationName:OBSERVATION_UPDATE object:self userInfo:note];
		
		return;
	}
	
	if (searching)
		return;
		
	BluetoothHCIVersionInfo * bluetooth = malloc (sizeof (bluetooth));
	NumVersion version;

	IOBluetoothGetVersion (&version, bluetooth);
	
	if (bluetooth->hciVersion)
	{
		searching = YES;

		if (search != nil)
		{
			[search clearFoundDevices];
			[search release];
		}
		
		search = [[IOBluetoothDeviceInquiry inquiryWithDelegate:self] retain];
		[search setUpdateNewDeviceNames:YES];
		[search setSearchCriteria:kBluetoothServiceClassMajorAny majorDeviceClass:kBluetoothDeviceClassMajorAny
					minorDeviceClass:kBluetoothDeviceClassMinorAny]; 
		
		[search start];
	}
	else
	{
		searching = NO;
		return;
	}
}

/* - (void) log:(NSArray *) devices
{
	NSString * logPath = [NSString stringWithFormat:@"%@/Desktop/bluetooth.xml", NSHomeDirectory ()];
	NSXMLDocument * doc = nil;

	NSError * error = nil;

	if ([[NSFileManager defaultManager] fileExistsAtPath:logPath])
		doc = [[NSXMLDocument alloc] initWithContentsOfURL:[NSURL fileURLWithPath:logPath] options:0 error:&error];

	if (doc == nil)
		doc = [[NSXMLDocument alloc] initWithXMLString:@"<log />" options:0 error:&error];

	[doc setCharacterEncoding:@"UTF-8"];
	
	NSXMLElement * snapshot = [[NSXMLElement alloc] initWithName:@"snapshot"];
	[snapshot addAttribute:[NSXMLNode attributeWithName:@"date" stringValue:[[NSDate date] description]]];
	[snapshot addAttribute:[NSXMLNode attributeWithName:@"location" stringValue:location]];
	
	for (IOBluetoothDevice * device in devices)
	{
		NSXMLElement * deviceElement = [[NSXMLElement alloc] initWithName:@"device"];

		[deviceElement addAttribute:[NSXMLNode attributeWithName:@"address" stringValue:[device getAddressString]]];
		[deviceElement addAttribute:[NSXMLNode attributeWithName:@"name" stringValue:[device getNameOrAddress]]];
		
		NSArray * services = [device getServices];
		
		if (services == nil)
			[device performSDPQuery:self];
		else
		{
			for (IOBluetoothSDPServiceRecord * record in [device getServices])
			{
				NSXMLElement * sdpRecord = [[NSXMLElement alloc] initWithName:@"service"];
				
				[sdpRecord addAttribute:[NSXMLNode attributeWithName:@"name" stringValue:[record getServiceName]]];

				// NSLog (@"%@:", [device getNameOrAddress]);
				
				// NSDictionary * attributes = [record getAttributes];
				
				// for (NSNumber * key in [attributes allKeys])
				// 	NSLog (@"%@ = %@", key, [attributes objectForKey:key]);
				
				[deviceElement addChild:sdpRecord];
			}
		}
		// Add service queries
		
		
		[snapshot addChild:deviceElement];
	}

	[[doc rootElement] addChild:snapshot];
	
	[[doc XMLData] writeToFile:logPath atomically:YES];

	[doc release];
} */

- (void) deviceInquiryComplete:(IOBluetoothDeviceInquiry *) sender error:(IOReturn) error aborted:(BOOL)aborted
{
	NSMutableArray * foundDevices = [NSMutableArray array];
	
	for (IOBluetoothDevice * device in [sender foundDevices])
		[foundDevices addObject:[device getNameOrAddress]];
		
	// if ([[NSUserDefaults standardUserDefaults] boolForKey:LOG_BLUETOOTH])
	// [self log:[sender foundDevices]];

	NSMutableDictionary * note = [NSMutableDictionary dictionary];
	
	[note setValue:@"Bluetooth Devices" forKey:OBSERVATION_SENSOR];
	[note setValue:foundDevices forKey:OBSERVATION_OBSERVATION];
	[note setValue:[NSNumber numberWithInteger:300] forKey:OBSERVATION_LIFESPAN];
	
	[[NSNotificationCenter defaultCenter] postNotificationName:OBSERVATION_UPDATE object:self userInfo:note];

	note = [NSMutableDictionary dictionary];
	
	[note setValue:@"Bluetooth Device Count" forKey:OBSERVATION_SENSOR];
	[note setValue:[NSNumber numberWithInteger:[foundDevices count]] forKey:OBSERVATION_OBSERVATION];
	[note setValue:[NSNumber numberWithInteger:300] forKey:OBSERVATION_LIFESPAN];
	
	[[NSNotificationCenter defaultCenter] postNotificationName:OBSERVATION_UPDATE object:self userInfo:note];
	
	searching = NO;
}

@end
